package org.black.phoneUtility.sms.reply.widget;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.black.phoneUtility.R;
import org.black.phoneUtility.sms.reply.database.dataModel.SmsReply;
import org.black.phoneUtility.sms.reply.provider.SmsReplyContract;
import org.black.phoneUtility.sms.reply.service.SmsReplyService;
import org.black.phoneUtility.sms.reply.service.exception.NoPhoneMessageException;
import org.black.phoneUtility.sms.reply.service.exception.NoReplyMessageException;
import org.black.phoneUtility.sms.reply.service.exception.NoSmsMessageException;
import org.black.phoneUtility.sms.reply.service.exception.ReplyDateTimeExpiredException;
import org.black.phoneUtility.sms.reply.service.exception.ReplyDateTimeInvalidException;
import org.black.phoneUtility.sms.reply.service.exception.SmsReplyNotExistException;
import org.black.phoneUtility.sms.reply.util.DateTimeUtil;

import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.Context;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.os.RemoteException;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

public class SmsReplyListCursorAdapter extends CursorAdapter {
	private static final String LOG_TAG = SmsReplyListCursorAdapter.class
			.getName();

	final static class ViewHolder {
		TextView titleTextView;
		Switch activatedSwitch;
		ImageView silentImageView;

		RelativeLayout detailRelativeLayout;
		TextView detailReplyStartTextView;
		TextView detailReplyEndTextView;
		TextView detailReplyRepeatTextView;
	}

	// private

	private Context context;
	private Map<Long, Boolean> selectionItems;
	private LayoutInflater layoutInflater;
	private SmsReplyService smsReplyService;

	public SmsReplyListCursorAdapter(Context context, Cursor cursor, int flag) {
		super(context, cursor, flag);
		this.context = context;
		this.layoutInflater = LayoutInflater.from(this.context);
		this.selectionItems = new HashMap<Long, Boolean>();
		this.smsReplyService = new SmsReplyService(this.context);
	}

	public void addSelection(int position, boolean checked) {
		this.selectionItems.put(getItemId(position), checked);
		this.notifyDataSetChanged();
	}

	public void removeSelection(int position) {
		this.selectionItems.remove(getItemId(position));
		this.notifyDataSetChanged();
	}

	public void removeSelections() {
		List<Long> smsReplies = new ArrayList<Long>();
		Set<Long> keys = this.selectionItems.keySet();
		for (Long key : keys) {
			boolean checked = this.selectionItems.get(key);
			if (checked == true) {
				smsReplies.add(key);
			}
		}

		ArrayList<ContentProviderOperation> contentProviderOperations = new ArrayList<ContentProviderOperation>();
		for (Long id : smsReplies) {
			ContentProviderOperation.Builder builder = ContentProviderOperation
					.newDelete(SmsReplyContract.SmsReplies.CONTENT_URI)
					.withSelection(SmsReplyContract.SmsReplies._ID + " = ? ",
							new String[] { id.toString() });
			contentProviderOperations.add(builder.build());
		}

		try {
			ContentProviderResult[] results = this.context.getContentResolver()
					.applyBatch(SmsReplyContract.AUTHORITY,
							contentProviderOperations);
			Log.v(LOG_TAG, Arrays.toString(results));
		} catch (RemoteException e) {
			Log.e(LOG_TAG, "RemoteException", e);
		} catch (OperationApplicationException e) {
			Log.e(LOG_TAG, "OperationApplicationException", e);
		}
		this.notifyDataSetChanged();
	}

	public void copy() {
		try {
			Set<Long> keys = this.selectionItems.keySet();
			for (Long key : keys) {
				boolean checked = this.selectionItems.get(key);
				if (checked == true) {
					this.smsReplyService.copy(key);
					break;
				}
			}
		} catch (RemoteException e) {
			Log.e(LOG_TAG, "RemoteException", e);
		} catch (OperationApplicationException e) {
			Log.e(LOG_TAG, "OperationApplicationException", e);
		}
	}

	public void clearSelection() {
		this.selectionItems.clear();
		this.notifyDataSetChanged();
	}

	public boolean isPositionChecked(int position) {
		Boolean result = this.selectionItems.get(position);
		return result == null ? false : result;
	}

	@Override
	public void bindView(View view, final Context context, final Cursor cursor) {
		view.findViewById(R.id.smsReplyRowTitleTextView);
		final ViewHolder viewHolder = (ViewHolder) view.getTag();
		viewHolder.titleTextView.setText(cursor.getString(cursor
				.getColumnIndex(SmsReplyContract.SmsReplies.TITLE)));
		viewHolder.activatedSwitch.setTag(cursor.getInt(cursor
				.getColumnIndex(SmsReplyContract.SmsReplies._ID)));
		viewHolder.activatedSwitch.setOnCheckedChangeListener(null);
		viewHolder.activatedSwitch
				.setChecked(cursor.getInt(cursor
						.getColumnIndex(SmsReplyContract.SmsReplies.IS_ACTIVATED)) == 1 ? true
						: false);
		viewHolder.silentImageView
				.setVisibility(cursor.getInt(cursor
						.getColumnIndex(SmsReplyContract.SmsReplies.ENABLE_RINGER_MODE_SILENT)) == 1 ? View.VISIBLE
						: View.GONE);
		viewHolder.activatedSwitch
				.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

					@Override
					public void onCheckedChanged(CompoundButton buttonView,
							boolean isChecked) {
						long id = (Integer) buttonView.getTag();
						boolean result = false;
						String message = null;
						try {
							result = smsReplyService
									.switchSmsReplyActivateStatus(id);
						} catch (NoPhoneMessageException e) {
							Log.e(LOG_TAG, e.getMessage(), e);
							message = context
									.getString(R.string.sms_reply_error_no_phone_message);
						} catch (NoReplyMessageException e) {
							Log.e(LOG_TAG, e.getMessage(), e);
							message = context
									.getString(R.string.sms_reply_error_no_reply_message);
						} catch (NoSmsMessageException e) {
							Log.e(LOG_TAG, e.getMessage(), e);
							message = context
									.getString(R.string.sms_reply_error_no_sms_message);
						} catch (ReplyDateTimeInvalidException e) {
							Log.e(LOG_TAG, e.getMessage(), e);
							message = context
									.getString(R.string.sms_reply_error_reply_date_time_is_invalid);
						} catch (SmsReplyNotExistException e) {
							Log.e(LOG_TAG, e.getMessage(), e);
							message = context
									.getString(R.string.sms_reply_error_not_exist);
						} catch (ReplyDateTimeExpiredException e) {
							Log.e(LOG_TAG, e.getMessage(), e);
							message = context
									.getString(R.string.sms_reply_error_reply_date_time_has_expired);
						} catch (RemoteException e) {
							Log.e(LOG_TAG, e.getMessage(), e);
						} catch (OperationApplicationException e) {
							Log.e(LOG_TAG, e.getMessage(), e);
						} finally {
							buttonView.setChecked(result);
						}
						if (TextUtils.isEmpty(message) == false) {
							Toast.makeText(context, message, Toast.LENGTH_SHORT)
									.show();
						}

					}
				});
		Integer cacheReplyDateTimeModeType = null;
		if (cursor
				.isNull(cursor
						.getColumnIndex(SmsReplyContract.SmsReplies.REPLY_DATE_TIME_TYPE)) == false) {
			cacheReplyDateTimeModeType = cursor
					.getInt(cursor
							.getColumnIndex(SmsReplyContract.SmsReplies.REPLY_DATE_TIME_TYPE));
		}
		if (cacheReplyDateTimeModeType == null) {
			viewHolder.detailReplyStartTextView.setText("");
			viewHolder.detailReplyEndTextView.setText("");
			viewHolder.detailReplyRepeatTextView.setText("");
		} else {
			if (cacheReplyDateTimeModeType == SmsReply.REPLY_DATE_TIME_MODE_ALWAYS_TYPE) {
				viewHolder.detailReplyStartTextView
						.setText(context
								.getString(R.string.sms_reply_row_detail_always_reply_right_now));
				viewHolder.detailReplyEndTextView
						.setText(context
								.getString(R.string.sms_reply_row_detail_always_reply_never_end));
				viewHolder.detailReplyRepeatTextView.setText("");
			} else if (cacheReplyDateTimeModeType == SmsReply.REPLY_DATE_TIME_MODE_EXPIRED_AFTER_TYPE) {
				boolean isActivated = false;
				if (cursor
						.getInt(cursor
								.getColumnIndex(SmsReplyContract.SmsReplies.IS_ACTIVATED)) == 1) {
					isActivated = true;
				}

				long expiredAfterMilliseconds = cursor
						.getLong(cursor
								.getColumnIndex(SmsReplyContract.SmsReplies.EXPIRATED_AFTER_MILLISECONDS));
				viewHolder.detailReplyRepeatTextView.setText("");
				if (isActivated == false) {
					long hours = DateTimeUtil
							.extractHoursFromDateTimeInMilliSeconds(expiredAfterMilliseconds);
					long minutes = DateTimeUtil
							.extractMinutesFromDateTimeInMilliSeconds(expiredAfterMilliseconds);

					viewHolder.detailReplyStartTextView.setText("");
					viewHolder.detailReplyEndTextView
							.setText(context
									.getString(
											R.string.sms_reply_row_detail_reply_expired_after_minutes,
											(hours < 10 ? "0" + hours : hours)
													+ ":"
													+ (minutes < 10 ? "0"
															+ minutes : minutes)));
				} else {
					Date startDateTime = new Date(
							cursor.getLong(cursor
									.getColumnIndex(SmsReplyContract.SmsReplies.ACTIVATION_DATE_TIME)));

					Date endDateTime = new Date(
							startDateTime.getTime()
									+ cursor.getLong(cursor
											.getColumnIndex(SmsReplyContract.SmsReplies.EXPIRATED_AFTER_MILLISECONDS)));
					viewHolder.detailReplyStartTextView.setText(DateFormat
							.getDateFormat(context).format(startDateTime)
							+ " "
							+ DateFormat.getTimeFormat(context).format(
									startDateTime));
					viewHolder.detailReplyEndTextView.setText(DateFormat
							.getDateFormat(context).format(endDateTime)
							+ " "
							+ DateFormat.getTimeFormat(context).format(
									endDateTime));
					viewHolder.detailReplyRepeatTextView.setText("");
				}
			} else if (cacheReplyDateTimeModeType == SmsReply.REPLY_DATE_TIME_MODE_PERIOD_TYPE) {
				Date startDateTime = new Date(
						cursor.getLong(cursor
								.getColumnIndex(SmsReplyContract.SmsReplies.PERIOD_START_DATE_TIME)));

				Date endDateTime = new Date(
						cursor.getLong(cursor
								.getColumnIndex(SmsReplyContract.SmsReplies.PERIOD_END_DATE_TIME)));
				viewHolder.detailReplyStartTextView.setText(DateFormat
						.getDateFormat(context).format(startDateTime)
						+ " "
						+ DateFormat.getTimeFormat(context).format(
								startDateTime));
				viewHolder.detailReplyEndTextView
						.setText(DateFormat.getDateFormat(context).format(
								endDateTime)
								+ " "
								+ DateFormat.getTimeFormat(context).format(
										endDateTime));
				viewHolder.detailReplyRepeatTextView.setText("");

			} else if (cacheReplyDateTimeModeType == SmsReply.REPLY_DATE_TIME_MODE_REPEAT_TYPE) {
				boolean isActivated = false;
				if (cursor
						.getInt(cursor
								.getColumnIndex(SmsReplyContract.SmsReplies.IS_ACTIVATED)) == 1) {
					isActivated = true;
				}
				boolean isSundayEndble = (cursor
						.getInt(cursor
								.getColumnIndex(SmsReplyContract.SmsReplies.IS_SUNDAY_ENABLE)) == 1 ? true
						: false);
				boolean isMondayEnable = (cursor
						.getInt(cursor
								.getColumnIndex(SmsReplyContract.SmsReplies.IS_MONDAY_ENABLE)) == 1 ? true
						: false);
				boolean isTuesdayEnable = (cursor
						.getInt(cursor
								.getColumnIndex(SmsReplyContract.SmsReplies.IS_TUESDAY_ENABLE)) == 1 ? true
						: false);
				boolean isWednesdayEnable = (cursor
						.getInt(cursor
								.getColumnIndex(SmsReplyContract.SmsReplies.IS_WEDNESDAY_ENABLE)) == 1 ? true
						: false);
				boolean isThursdayEnable = (cursor
						.getInt(cursor
								.getColumnIndex(SmsReplyContract.SmsReplies.IS_THURSDAY_ENABLE)) == 1 ? true
						: false);
				boolean isFridayEnable = (cursor
						.getInt(cursor
								.getColumnIndex(SmsReplyContract.SmsReplies.IS_FRIDAY_ENABLE)) == 1 ? true
						: false);
				boolean isSaturdayEnable = (cursor
						.getInt(cursor
								.getColumnIndex(SmsReplyContract.SmsReplies.IS_SATURDAY_ENABLE)) == 1 ? true
						: false);
				Date startDateTime = new Date(
						cursor.getLong(cursor
								.getColumnIndex(SmsReplyContract.SmsReplies.REPEAT_START_TIME)));
				Date endDateTime = new Date(
						cursor.getLong(cursor
								.getColumnIndex(SmsReplyContract.SmsReplies.REPEAT_END_TIME)));
				String startDateTimeString = null;
				String endDateTimeString = null;
				StringBuilder repeatStringBuilder = new StringBuilder();
				if (isSundayEndble == false && isMondayEnable == false
						&& isTuesdayEnable == false
						&& isWednesdayEnable == false
						&& isThursdayEnable == false && isFridayEnable == false
						&& isSaturdayEnable == false) {
					if (isActivated == false) {
						startDateTimeString = DateFormat.getTimeFormat(context)
								.format(startDateTime);
						endDateTimeString = DateFormat.getTimeFormat(context)
								.format(endDateTime);
					} else {
						startDateTimeString = DateFormat.getDateFormat(context)
								.format(startDateTime)
								+ " "
								+ DateFormat.getTimeFormat(context).format(
										startDateTime);
						endDateTimeString = DateFormat.getDateFormat(context)
								.format(endDateTime)
								+ " "
								+ DateFormat.getTimeFormat(context).format(
										endDateTime);
					}
					repeatStringBuilder.append(context
							.getString(R.string.never));
				} else {
					startDateTimeString = DateFormat.getTimeFormat(context)
							.format(startDateTime);
					endDateTimeString = DateFormat.getTimeFormat(context)
							.format(endDateTime);
					if (isSundayEndble == true && isMondayEnable == true
							&& isTuesdayEnable == true
							&& isWednesdayEnable == true
							&& isThursdayEnable == true
							&& isFridayEnable == true
							&& isSaturdayEnable == true) {
						repeatStringBuilder.append(context
								.getString(R.string.everyday));
					} else {
						boolean isAppended = false;
						String comma = context.getString(R.string.comma);
						if (isSundayEndble == true) {
							if (isAppended == false) {
								isAppended = true;
							} else {
								repeatStringBuilder.append(comma);
							}
							repeatStringBuilder.append(context
									.getString(R.string.sunday_abbreviation));
						}
						if (isMondayEnable == true) {
							if (isAppended == false) {
								isAppended = true;
							} else {
								repeatStringBuilder.append(comma);
							}
							repeatStringBuilder.append(context
									.getString(R.string.monday_abbreviation));

						}
						if (isTuesdayEnable == true) {
							if (isAppended == false) {
								isAppended = true;
							} else {
								repeatStringBuilder.append(comma);
							}
							repeatStringBuilder.append(context
									.getString(R.string.tuesday_abbreviation));

						}
						if (isWednesdayEnable == true) {
							if (isAppended == false) {
								isAppended = true;
							} else {
								repeatStringBuilder.append(comma);
							}
							repeatStringBuilder
									.append(context
											.getString(R.string.wednesday_abbreviation));

						}
						if (isThursdayEnable == true) {
							if (isAppended == false) {
								isAppended = true;
							} else {
								repeatStringBuilder.append(comma);
							}
							repeatStringBuilder.append(context
									.getString(R.string.thursday_abbreviation));
						}
						if (isFridayEnable == true) {
							if (isAppended == false) {
								isAppended = true;
							} else {
								repeatStringBuilder.append(comma);
							}
							repeatStringBuilder.append(context
									.getString(R.string.friday_abbreviation));

						}
						if (isSaturdayEnable == true) {
							if (isAppended == false) {
								isAppended = true;
							} else {
								repeatStringBuilder.append(comma);
							}
							repeatStringBuilder.append(context
									.getString(R.string.saturday_abbreviation));
						}
					}
				}

				viewHolder.detailReplyStartTextView
						.setText(startDateTimeString);
				viewHolder.detailReplyEndTextView.setText(endDateTimeString);
				viewHolder.detailReplyRepeatTextView
						.setText(repeatStringBuilder.toString());
			} else {
				// TODO: something error
			}
		}

		if (this.selectionItems.get(cursor.getLong(cursor
				.getColumnIndex(SmsReplyContract.SmsReplies._ID))) != null
				&& this.selectionItems.get(cursor.getLong(cursor
						.getColumnIndex(SmsReplyContract.SmsReplies._ID))) == true) {
			view.setBackgroundColor(this.context.getResources().getColor(
					android.R.color.holo_blue_light));
		} else {
			view.setBackground(this.context.getResources().getDrawable(
					android.R.drawable.list_selector_background));
		}
	}

	@Override
	public View newView(Context context, final Cursor cursor, ViewGroup parent) {
		View result = this.layoutInflater.inflate(R.layout.sms_reply_row,
				parent, false);
		ViewHolder viewHolder = new ViewHolder();
		viewHolder.titleTextView = (TextView) result
				.findViewById(R.id.smsReplyRowTitleTextView);
		viewHolder.activatedSwitch = (Switch) result
				.findViewById(R.id.smsReplyRowActivatedSwitch);
		viewHolder.detailRelativeLayout = (RelativeLayout) result
				.findViewById(R.id.smsReplyRowDetailRelativeLayout);
		viewHolder.detailReplyStartTextView = (TextView) result
				.findViewById(R.id.smsReplyRowDetailReplyStartTextView);
		viewHolder.detailReplyEndTextView = (TextView) result
				.findViewById(R.id.smsReplyRowDetailReplyEndTextView);
		viewHolder.detailReplyRepeatTextView = (TextView) result
				.findViewById(R.id.smsReplyRowDetailReplyRepeatTextView);
		viewHolder.silentImageView = (ImageView) result
				.findViewById(R.id.silentTurnOnImageView);
		result.setTag(viewHolder);
		return result;
	}
}
